package com.hzw.saas.common.util;

import java.util.*;
import java.util.stream.Collectors;

import com.hzw.saas.common.util.constants.PathConsts;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrSplitter;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import lombok.experimental.UtilityClass;

/**
 * 文件工具类
 *
 * @author zzl
 * @since 12/28/2020
 */
@UtilityClass
public class PathUtils {

    /**
     * 标准化通用路径, 使用'/'作为路径分隔符
     *
     * @param path 待处理路径
     * @return 处理后的路径
     */
    public static String normalizePath(String path) {
        return normalizePath(path, null, null);
    }

    /**
     * 标准化通用路径, 使用'/'作为路径分隔符
     *
     * @param path           待处理路径
     * @param keepStartSlash 是否保留首位'/', true(无则添加)/false(有则删除)/null(不处理)
     * @param keepEndSlash   是否保留末位'/', true(无则添加)/false(有则删除)/null(不处理)
     * @return 处理后的路径
     */
    public static String normalizePath(String path, Boolean keepStartSlash, Boolean keepEndSlash) {
        if (StrUtil.isBlank(path)) {
            return StrUtil.EMPTY;
        }
        path = path.replaceAll(PathConsts.MORE_SLASH_SPACE_PATTERN, PathConsts.SLASH);
        if (Objects.nonNull(keepStartSlash)) {
            if (keepStartSlash && !path.startsWith(PathConsts.SLASH)) {
                path = PathConsts.SLASH + path;
            }
            if (!keepStartSlash && path.startsWith(PathConsts.SLASH)) {
                path = path.substring(1);
            }
        }
        if (Objects.nonNull(keepEndSlash)) {
            if (!keepEndSlash && path.endsWith(PathConsts.SLASH)) {
                path = path.substring(0, path.length() - 1);
            }
            if (keepEndSlash && !path.endsWith(PathConsts.SLASH)) {
                path = path.concat(PathConsts.SLASH);
            }
        }
        // 增加对://的支持
        path = path.replaceAll(":[/\\\\]+", "://");
        return path;
    }

    /**
     * 批量标准化通用路径
     */
    public static String[] normalizePaths(String[] paths) {
        return normalizePaths(paths, null, null);
    }

    /**
     * 批量标准化通用路径
     */
    public static List<String> normalizePaths(List<String> paths) {
        return normalizePaths(paths, null, null);
    }

    /**
     * 批量标准化通用路径
     */
    public static String[] normalizePaths(String[] paths, Boolean keepStartSlash, Boolean keepEndSlash) {
        if (ArrayUtil.isEmpty(paths)) {
            return new String[0];
        }
        return Arrays.stream(paths).map(path -> normalizePath(path, keepStartSlash, keepEndSlash)).toArray(String[]::new);
    }

    /**
     * 批量标准化通用路径
     */
    public static List<String> normalizePaths(List<String> paths, Boolean keepStartSlash, Boolean keepEndSlash) {
        if (CollUtil.isEmpty(paths)) {
            return new ArrayList<>();
        }
        return paths.stream().map(path -> normalizePath(path, keepStartSlash, keepEndSlash)).collect(Collectors.toList());
    }

    /**
     * 标准化绝对路径
     */
    public static String normalizeAbsolutePath(String path, boolean keepEndSlash) {
        return normalizePath(path, true, keepEndSlash);
    }

    /**
     * 连接路径并标准化，使用'/'作为路径分隔符
     *
     * @param root  首路径
     * @param paths 待拼接路径
     * @return 拼接后的路径
     */
    public static String connectPath(String root, String... paths) {
        return connectPath(root, null, null, paths);
    }

    /**
     * 连接路径并标准化，使用'/'作为路径分隔符
     *
     * @param root  首路径
     * @param paths 待拼接路径
     * @return 拼接后的路径
     */
    public static String connectPath(String root, Collection<String> paths) {
        return connectPath(root, null, null, paths);
    }

    /**
     * 连接路径并标准化，使用'/'作为路径分隔符
     *
     * @param root           首路径
     * @param keepStartSlash 是否保留首位'/', true(无则添加)/false(有则删除)/null(不处理)
     * @param keepEndSlash   是否保留末位'/', true(无则添加)/false(有则删除)/null(不处理)
     * @param paths          待拼接路径
     * @return 拼接后的路径
     */
    public static String connectPath(String root, Boolean keepStartSlash, Boolean keepEndSlash, String... paths) {
        return connectPath(root, keepStartSlash, keepEndSlash, Arrays.asList(paths));
    }

    /**
     * 连接路径并标准化，使用'/'作为路径分隔符
     *
     * @param root           首路径
     * @param keepStartSlash 是否保留首位'/', true(无则添加)/false(有则删除)/null(不处理)
     * @param keepEndSlash   是否保留末位'/', true(无则添加)/false(有则删除)/null(不处理)
     * @param paths          待拼接路径
     * @return 拼接后的路径
     */
    public static String connectPath(String root, Boolean keepStartSlash, Boolean keepEndSlash, Collection<String> paths) {
        if (StrUtil.isBlank(root)) {
            root = StrUtil.EMPTY;
        }
        if (Objects.isNull(paths)) {
            return root;
        }
        StringBuilder builder = new StringBuilder(root);
        for (String path : paths) {
            if (Objects.isNull(path)) {
                continue;
            }
            builder.append(PathConsts.SLASH).append(path.trim());
        }
        return normalizePath(builder.toString(), keepStartSlash, keepEndSlash);
    }

    /**
     * 连接uri路径并标准化，使用'/'作为路径分隔符, 移除末位'/'
     *
     * @param root  首路径
     * @param paths 待拼接路径
     * @return 拼接后的路径
     */
    public static String connectUri(String root, String... paths) {
        return connectPath(root, null, false, paths);
    }

    /**
     * 连接uri路径并标准化，使用'/'作为路径分隔符, 移除末位'/'
     *
     * @param root  首路径
     * @param paths 待拼接路径
     * @return 拼接后的路径
     */
    public static String connectUri(String root, List<String> paths) {
        return connectPath(root, null, false, paths);
    }

    /**
     * 获取路径对应的目录名列表
     *
     * @param path 路径字符串
     * @return 路径名称列表
     */
    public static List<String> listNames(String path) {
        return StrSplitter.splitByRegex(path, PathConsts.ALL_SLASH_PATTERN, 0, true, true);
    }

    /**
     * 是否为父子路径关系
     */
    public static boolean isSub(String supPath, String subPath) {
        supPath = normalizePath(supPath, false, false);
        subPath = normalizePath(subPath, false, false);
        return subPath.startsWith(supPath);
    }


}
